home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / DiskUtil / Crunch / XFH.lha / XFH / SRC / FILE.C < prev    next >
C/C++ Source or Header  |  1993-03-10  |  8KB  |  246 lines

  1. /* file.c - file-handle stuff for the XFH file system handler.
  2.    Copyright (C) 1991, 1992, 1993 Kristian Nielsen.
  3.  
  4.    This file is part of XFH, the compressing file system handler.
  5.  
  6.    This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2 of the License, or
  9.    (at your option) any later version.
  10.  
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            */
  19.  
  20. #include "CFS.h"
  21.  
  22. #include <string.h>
  23.  
  24. #include <dossupport.h>
  25.  
  26.  
  27. /*
  28.  * RawCFSOpen() is the low-lewel Open() function of the CFS file
  29.  * system. It takes a simple filename (that is, no path specification),
  30.  * a lock to the parent directory, and a 'mode' value as arguments. A
  31.  * special case occurs for a null name, in which case it opens the file
  32.  * associated with the passed lock.
  33.  */
  34.  
  35. struct CFSFH *RawCFSOpen(glb glob, struct CFSLock *lock,
  36.                         char * name, LONG mode ){
  37.    struct FileHandle *xfh;
  38.    void *fh;
  39.  
  40.    /* Here is the place to check whether the lock refers to a
  41.     * directory in the underlying file system, or if it is in fact
  42.     * a directory in an archieve. This code is for the former case: */
  43.  
  44.    if( lock->objtype == XOBJECT ){
  45.       LONG type;
  46.       BOOL isnew = FALSE;   /* Whether MODE_READWRITE file is new. */
  47.  
  48.       /* ToDo: Need better way to determine the correct action. */
  49.       if( mode != MODE_OLDFILE && mode != MODE_NEWFILE && mode != MODE_READWRITE ){
  50.          debug(("Error: RawCFSOpen(): Unsupported Open() mode %ld\n",mode));
  51.          glob->ioerr = ERROR_ACTION_NOT_KNOWN;
  52.          return NULL;
  53.       }
  54.  
  55.       if(mode==MODE_READWRITE){
  56.          /* Check that append mode is allowed. */
  57.          if(!glob->allowappend){
  58.             debug(("Append mode not set... failing.\n"));
  59.             glob->ioerr = ERROR_ACTION_NOT_KNOWN;
  60.             return NULL;
  61.          }
  62.          /* Try to determine whether file already exists. NOTE: this is
  63.           * NOT fool-proof, since there is a (slight) change that the
  64.           * file may suddenly appear just before the xOpen() call.
  65.           */
  66.          isnew = !xExists1(glob, lock->xlock, name);
  67.       }
  68.       if( !(xfh=xOpen(glob, lock->xlock, name, mode)) ){
  69.          debug(("RawCFSOpen(): Object %s could not be opened: %d.\n",name,glob->ioerr));
  70.          return NULL;
  71.       }
  72.       if( mode == MODE_NEWFILE ){
  73.          /* NOTE: the name cannot be "" (since then it's already in use). */
  74.          if(!strcmp(name,"")){
  75.             debug(("Strange...empty name in open new file - failing.\n"));
  76.             xClose(glob, xfh);
  77.             xDeleteFile(glob, lock->xlock, name);
  78.             glob->ioerr = ERROR_OBJECT_IN_USE;
  79.             return NULL;
  80.          }
  81.          if(!(fh = XObjCreateFH(glob, xfh, mode, name, lock))){
  82.             SAVEIOERR;
  83.             xClose(glob, xfh);
  84.             xDeleteFile(glob, lock->xlock, name);
  85.             RESTIOERR;
  86.             return NULL;
  87.          }
  88.       }else{   /* MODE_OLDFILE or MODE_READWRITE */
  89.          type = xFileType( glob, xfh );
  90.          /* 'type' will be XObj for new file created with MODE_READWRITE. */
  91.          if( type == XPKOBJECT ){
  92.             if( mode==MODE_OLDFILE ){
  93.                struct CFSFH *newfh=(struct CFSFH *)XpkOpenOldFile( glob, xfh );
  94.                if(!newfh){
  95.                   SAVEIOERR;
  96.                   xClose(glob,xfh);
  97.                   RESTIOERR;
  98.                   return NULL;
  99.                }
  100.            /* Ready for Write() if needed. */
  101.            if(!XObjStuffFH(glob, newfh, name, lock)){
  102.          SAVEIOERR;
  103.          Xpk_Close(glob, (struct XpkFH *)newfh);
  104.          RESTIOERR;
  105.          return NULL;
  106.            }
  107.                fh = newfh;
  108.             }else{     /* MODE_READWRITE */
  109.                BOOL res;
  110.                
  111.                xClose(glob,xfh);
  112.                debug(("Attempting to uncompress file %s.\n",name));
  113.                res = TransformFile(glob, lock->xlock, name, UnPackFile2File, NULL);
  114.                debug(("TransformFile() returned: %ld.\n",res));
  115.                if(!res) return NULL;
  116.                if( !(xfh=xOpen(glob, lock->xlock, name, mode)) ){
  117.                   debug(("Error: File %s could not be re-opened: %d.\n",name,glob->ioerr));
  118.                   return NULL;
  119.                }
  120.                fh = XObjCreateFH(glob, xfh, mode, name, lock);
  121.                if(!fh){
  122.                   SAVEIOERR;
  123.                   xClose(glob, xfh);
  124.                   RESTIOERR;
  125.                   return NULL;
  126.                }
  127.             }
  128.          }else{
  129.             /* A plain file. If the mode is MODE_READWRITE and the file
  130.              * was newly created, the user can request the file to be
  131.              * autocompressed. Otherwise, the file will not be compressed.
  132.              */
  133.             if(mode==MODE_READWRITE && isnew && glob->compressreadwrite){
  134.                fh = XObjCreateFH(glob, xfh, mode, name, lock);
  135.             }else{
  136.                fh = XObjCreateFH(glob, xfh, mode, NULL, NULL);
  137.             }
  138.             if(!fh){
  139.                SAVEIOERR;
  140.                xClose(glob, xfh);
  141.                RESTIOERR;
  142.                return NULL;
  143.             }
  144.          }
  145.       }
  146.    }else if( lock->objtype == XPKOBJECT ){  /* Allow Open(xpklock,""). */
  147.       if( mode != MODE_OLDFILE ){
  148.          debug(("Bad open from XpkLock (mode=%ld).\n",mode));
  149.          if(!strcmp(name,"")){
  150.             glob->ioerr = ERROR_OBJECT_IN_USE;
  151.          }else{
  152.             glob->ioerr = ERROR_OBJECT_WRONG_TYPE;
  153.          }
  154.          return NULL;
  155.       }else if(strcmp(name,"")){
  156.          debug(("Bad open (non-null filename) from Xpklock.\n"));
  157.          glob->ioerr = ERROR_OBJECT_WRONG_TYPE;
  158.          return NULL;
  159.       }else{
  160.          struct CFSFH *newfh = (struct CFSFH *)
  161.        XpkOpenOldFileFromCopyOfLock( glob, (struct XpkLock *)lock );
  162.          if(!newfh){
  163.             return NULL;
  164.          }
  165.      /* Ready for Write() if needed. */
  166.      if(!XObjStuffFH(glob, newfh, name, lock)){
  167.        SAVEIOERR;
  168.        Xpk_Close(glob, (struct XpkFH *)newfh);
  169.        RESTIOERR;
  170.        return NULL;
  171.      }
  172.          fh = newfh;
  173.       }
  174.    }else{
  175.       debug(("** PANIC **: bad object type in lock: %ld\n",lock->objtype));
  176.       glob->ioerr = ERROR_OBJECT_WRONG_TYPE;
  177.       return NULL;
  178.    }
  179.    return fh;
  180. }
  181.  
  182.  
  183. struct CFSFH *CFSOpen(glb glob,struct CFSLock * parentlock,
  184.                           char * name,LONG mode){
  185.    struct CFSLock *parent;
  186.    struct CFSFH *fh;
  187.    LONG saveioerr;
  188.    
  189.    /* Lock the parent directory, and set 'name' to point to the actual
  190.     * name. For a path like 'name:', lock the file/dir and point name to
  191.     * "".
  192.     */
  193.    if(!(parent = CFSLockParent(glob, parentlock, &name ))){
  194.       debug(("Error: CFSOpen(): Could not CFSLockParent(): %ld.\n",glob->ioerr));
  195.       return NULL;
  196.    }
  197.    
  198.    /* Now Lock the file or dir. */
  199.    fh = RawCFSOpen( glob, parent, name, mode );
  200.    saveioerr = glob->ioerr;
  201.    CFSUnLock( glob, parent );
  202.    glob->ioerr = saveioerr;
  203.    
  204.    return fh;
  205. }
  206.  
  207.  
  208. BOOL CFSClose( glb glob, struct CFSFH *fh ){
  209.  
  210.    if( !fh ) return DOSTRUE;
  211.    return (BOOL) (*fh->f->Close)( glob, fh );
  212. }
  213.  
  214.  
  215. LONG CFSRead( glb glob, struct CFSFH *fh, void *buf, LONG len ){
  216.    
  217.    if( !fh )
  218.       return 0L;
  219.    else
  220.       return (*fh->f->Read)( glob, fh, buf, len );
  221. }
  222.  
  223.  
  224. LONG CFSWrite( glb glob, struct CFSFH *fh, void *buf, LONG len ){
  225.    
  226.    if( !fh )
  227.       return 0L;
  228.    else
  229.       return (*fh->f->Write)( glob, fh, buf, len );
  230. }
  231.  
  232.  
  233. LONG CFSSeek( glb glob, struct CFSFH *fh, LONG pos, LONG offset ){
  234.    
  235.    if( !fh )
  236.       return -1L;
  237.    else if( !fh->f ){
  238.       debug(("** PANIC **: CFSSeek(): NULL action func.\n"));
  239.       glob->ioerr = ERROR_OBJECT_WRONG_TYPE;
  240.       return -1L;
  241.    }else
  242.       return (*fh->f->Seek)( glob, fh, pos, offset );
  243. }
  244.  
  245. /* End of file.c */
  246.